Terraformで、同じ構成を複数プロビジョニングしたい: backend-configオプション編
先日 HashiTalks Japanで「シングルテナント構成のSaaSのIaCにTerraform Workspacesを導入してみた」というビデオ登壇をしました。その中で時間の都合でご紹介できなかった、「Workspacesを使う以外の、同じ構成(リソースセット)を複数個プロビジョニングする方法案」を、複数回に分けてご紹介していきます。
関連エントリ
- #HashiTalks Japanで「シングルテナント構成のSaaSのIaCにTerraform Workspacesを導入してみた」という発表をしました
- Terraformで、同じ構成を複数プロビジョニングしたい: Module編
- Terraformで、同じ構成を複数プロビジョニングしたい: ディレクトリ分割編
- Terraformで、同じ構成を複数プロビジョニングしたい: Terragruntでrun-all編
- Terraformで、同じ構成を複数プロビジョニングしたい: backend-configオプション編 ? イマココ
- Terraformで、同じ構成を複数プロビジョニングしたい: Terragruntでbackendを動的設定編
今回は
backend-config
オプション編です。
詳細
terraform.backend
ブロックの必須attributeを未設定にします。
terraform { required_version = "= 1.2.7" backend "s3" { # bucket = "hogehoge-terraform" # key = "dev.tfstate" # region = "us-east-1" } required_providers { aws = { version = "~> 4.26.0" } } }
そして terraform init
時にbackend-config
オプションを使って、未設定の分のbackendの設定を指定します。
% terraform init \ -backend-config="bucket=hogehoge-terraform"\ -backend-config="key=dev.tfstate"\ -backend-config="region=us-east-1"
ファイルにまとめてそのパスを指定することも可能です。
bucket = "hogehoge-terraform" key = "dev.tfstate" region = "us-east-1"
% terraform init -backend-config="./config.s3.tfbackend"
backend-config
オプションに指定する値を切り替えることで、複数の展開先にプロビジョニングすることができます。
一部のattributeはterraform.backend
ブロックに書いて、書いていないものだけbackend-config
オプションで設定することもできます。
terraform { required_version = "= 1.2.7" backend "s3" { bucket = "hogehoge-terraform" # key = "dev.tfstate" region = "us-east-1" } required_providers { aws = { version = "~> 4.26.0" } } }
また、一度backendの設定をした後に変更する場合は-reconfigure
も指定する必要があります。
% terraform init\ -backend-config="./config.s3.tfbackend"\ -reconfigure
もしくはルートモジュールディレクトリの.terraform
ディレクトリを削除します。
(CI環境のような毎回捨てる環境なら不要です)
この構成の良い点
展開先の情報がコードに出ない、Gitに残らない
Module案などと異なり展開先の情報がコードに現れないので、その情報を隠蔽化したい際には適しています。例えばシングルテナント構成のSaaSを作る際などには向いているでしょう。
backendの設定が自在
Terraform Workspacesに対する優位点です。
Workspacesを使う場合、Stateファイルの格納場所は固定です。S3をbackendに使う場合、Stateファイルはすべて同じバケット内のenv:/(workspace名)/(key名)
に格納されます。
例えばWorkspace案でクロスアカウントでプロビジョニングする場合、Stateファイル格納先は1アカウントに集中することになります。展開先のアカウントに別々に格納することはできません。
対してこの構成だともっと自由にStateファイル格納場所を選ぶことができます。オブジェクトパスはもちろん、バケットを別々にすることも、違うリージョンにすることも、別アカウントにすることもできますね。
この構成のイマイチな点
Terraform単体で使えない
この構成はBackendの設定をTerraformの外に出すことになります。ですので外出し先との連携無しでリソースの管理をすることができません。関係者に使用方法の共有を徹底する必要があるかと思います。
展開先ごとの差分の実現方法が限られる
展開先の情報が全くコードに出てこないので、もし展開先毎にプロビジョニングしたいリソースが異なるような要件があった場合、それを実現する方法は変数ファイル(.tfvars
)の値を変えるくらいしかありません。backend-configの設定と併せて、取り違いが起きないように慎重に管理する必要があります。
ユースケース
シングルテナント構成のSaaSのような、展開先毎のプロビジョニング内容にほぼほぼ差分がない、かつ展開先が多い場合に向いていると思います。